package com.tcm.ucenter.web.handler;

import com.auth0.jwt.exceptions.JWTVerificationException;
import com.base.core.lang.StringUtils;
import com.base.core.utils.JwtUtils;
import com.base.core.utils.R;
import com.tcm.ucenter.web.exception.TokenRuntimeException;
import io.jsonwebtoken.Claims;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 创建一个 token 拦截器.
 * 需要继承 HandlerInterceptorAdapter,并且声明为spring的组件
 * @author buker
 * @version 1.0.0
 * @since 1.0.0
 * <p>
 * Created at 2020/7/30 2:19 下午
 */
@Component
public class TokenInterceptor extends HandlerInterceptorAdapter {

 
  // 重写 前置拦截方法
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
    // 1、从请求头中获取token
    String token = request.getHeader("token");
    // 2、判断 token 是否存在
    if (token == null ||"".equals(token)) {
      // 这里可以自定义 抛出 token 异常
      throw new TokenRuntimeException("未登录");
    }

    // 3、解析token
    JwtUtils jwtUtils = new JwtUtils();
    try {
      jwtUtils.isVerify(token);
    }catch (JWTVerificationException e){
      R.throwFail(401, e.getMessage());
    }

    Claims claim = jwtUtils.decode(token);

    if (null == claim) {
      // 这里可以自定义 抛出 token 异常
      throw  new TokenRuntimeException("token 解析错误");
    }

    // 4、判断 token 是否过期
    boolean tokenExpired = JwtUtils.isTokenExpired(token);
    if (tokenExpired) {
      // 这里可以自定义 抛出 token 异常
      throw new TokenRuntimeException("token已过期，请重新登录");
    }

    // 5、 从 token 中获取员工信息
    Long userId = (Long) claim.get("userId");
    // 6、去数据库中匹配 id 是否存在 (这里直接写死了)
    if (null == userId) {
      // 这里可以自定义 抛出 token 异常
      throw new TokenRuntimeException("缺少用户id");
    }
 
    // 7、成功后 设置想设置的属性，比如员工姓名
    request.setAttribute("userId", userId);
    return true;
  }
}